package com.bpmn.system.service.impl;

import cn.dev33.satoken.secure.BCrypt;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.bpmn.common.exception.ServiceException;
import com.bpmn.system.domain.SysTenant;
import com.bpmn.system.domain.form.TenantForm;
import com.bpmn.system.domain.query.TenantQuery;
import com.bpmn.system.domain.vo.TenantVo;
import com.bpmn.system.mapper.SysTenantMapper;
import com.bpmn.system.service.ISysTenantService;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.UUID;

/**
 * @author rain
 */
@Service
public class SysTenantServiceImpl extends ServiceImpl<SysTenantMapper, SysTenant> implements ISysTenantService {

    @Override
    public IPage<TenantVo> listTenant(TenantQuery query) {
        LambdaQueryWrapper<SysTenant> wrapper = new LambdaQueryWrapper<>();
        wrapper.like(StringUtils.hasText(query.getName()), SysTenant::getName, query.getName())
                .like(StringUtils.hasText(query.getAppId()), SysTenant::getAppId, query.getAppId())
                .eq(query.getStatus() != null, SysTenant::getStatus, query.getStatus())
                .orderByDesc(SysTenant::getCreateTime);
        Page<SysTenant> page = new Page<>(query.getPageNum(), query.getPageSize());
        Page<SysTenant> tenantPage = this.page(page, wrapper);
        return tenantPage.convert(tenant -> {
            TenantVo vo = new TenantVo();
            BeanUtils.copyProperties(tenant, vo);
            return vo;
        });
    }

    @Override
    public void addTenant(TenantForm tenant) {
        // 检查租户AppID是否已存在
        if (baseMapper.exists(new LambdaQueryWrapper<SysTenant>()
                .eq(SysTenant::getAppId, tenant.getAppId()))) {
            throw new ServiceException("租户AppID已存在");
        }
        // 检查管理员账号是否已存在
        if (baseMapper.exists(new LambdaQueryWrapper<SysTenant>()
                .eq(SysTenant::getAdminUsername, tenant.getAdminUsername()))) {
            throw new ServiceException("管理员账号已存在");
        }
        SysTenant sysTenant = new SysTenant();
        BeanUtils.copyProperties(tenant, sysTenant);
        // 加密管理员密码
        sysTenant.setAdminPassword(BCrypt.hashpw(tenant.getAdminPassword()));
        this.save(sysTenant);
    }

    @Override
    public void updateTenant(TenantForm tenant) {
        SysTenant sysTenant = getById(tenant.getId());
        if (sysTenant == null) {
            throw new ServiceException("租户不存在");
        }
        // 检查AppID是否被其他租户使用
        if (!sysTenant.getAppId().equals(tenant.getAppId()) &&
                baseMapper.exists(new LambdaQueryWrapper<SysTenant>()
                        .eq(SysTenant::getAppId, tenant.getAppId()))) {
            throw new ServiceException("租户AppID已存在");
        }
        // 检查管理员账号是否被其他租户使用
        if (!sysTenant.getAdminUsername().equals(tenant.getAdminUsername()) &&
                baseMapper.exists(new LambdaQueryWrapper<SysTenant>()
                        .eq(SysTenant::getAdminUsername, tenant.getAdminUsername()))) {
            throw new ServiceException("管理员账号已存在");
        }
        SysTenant newTenant = new SysTenant();
        BeanUtils.copyProperties(tenant, newTenant);
        // 如果提供了新密码，则更新密码
        if (StrUtil.isNotBlank(tenant.getAdminPassword())) {
            newTenant.setAdminPassword(BCrypt.hashpw(tenant.getAdminPassword()));
        }
        this.updateById(sysTenant);
    }

    @Override
    public void deleteTenant(String id) {
        this.removeById(id);
    }

    @Override
    public String generateSecret() {
        return UUID.randomUUID().toString().replace("-", "");
    }

    @Override
    public void resetPassword(String id, String password) {
        SysTenant tenant = getById(id);
        if (tenant == null) {
            throw new ServiceException("租户不存在");
        }
        tenant.setAdminPassword(BCrypt.hashpw(password));
        baseMapper.updateById(tenant);
    }

    public static void main(String[] args) {
        System.out.println("BCrypt.hashpw(\"admin\") = " + BCrypt.hashpw("admin"));
    }


}